﻿using HslCommunication;
using HslCommunication.Profinet.Melsec;
using System;
using System.Linq;
using System.Threading.Tasks;

namespace SSC.PlcConnect
{
    internal class MitsubishiPlc : IPlcConnect
    {
        private static MitsubishiPlc _instance;
        private static readonly object _lock = new object();

        private MelsecMcNet _melsecMcNet;
        public string IpAddress { get; private set; }
        public int Port { get; private set; }
        public bool IsConnected { get; private set; }

        private MitsubishiPlc(string ipAddress, int port)
        {
            IpAddress = ipAddress;
            Port = port;
            _melsecMcNet = new MelsecMcNet(ipAddress, port);
        }

        public static void Initialize(string ipAddress, int port = 6000)
        {
            lock (_lock)
            {
                if (_instance != null)
                {
                    throw new InvalidOperationException("PLC连接已初始化，不能重复初始化！");
                }

                _instance = new MitsubishiPlc(ipAddress, port);
            }
        }

        public static MitsubishiPlc GetInstance()
        {
            if (_instance == null)
            {
                throw new InvalidOperationException("PLC连接尚未初始化，请先调用 Initialize 方法！");
            }
            return _instance;
        }

        public async Task<bool> ConnectAsync()
        {
            try
            {
                lock (_lock)
                {
                    if (IsConnected)
                    {
                        Console.WriteLine("已连接到PLC，无需重复连接！");
                        return true;
                    }
                }

                var result = await Task.Run(() => _melsecMcNet.ConnectServer());
                IsConnected = result.IsSuccess;
                Console.WriteLine(IsConnected ? "成功连接到PLC！" : $"连接失败: {result.Message}");
                return IsConnected;
            }
            catch (Exception ex)
            {
                Console.WriteLine($"连接过程中发生异常: {ex.Message}");
                return false;
            }
        }

        public async Task<short> ReadSingle(string address)
        {
            if (!IsConnected) throw new InvalidOperationException("请先连接到PLC！");
            try
            {
                var result = await Task.Run(() => _melsecMcNet.ReadInt16(address));
                if (result.IsSuccess)
                {
                    Console.WriteLine($"读取地址 {address} 成功：{result.Content}");
                    return result.Content;
                }
                else
                {
                    Console.WriteLine($"读取失败：{result.Message}");
                    return default;
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine($"读取数据时异常：{ex.Message}");
                return default;
            }
        }

        public async Task<short[]> ReadBatch(string address, ushort length)
        {
            if (!IsConnected) throw new InvalidOperationException("请先连接到PLC！");
            try
            {
                var result = await Task.Run(() => _melsecMcNet.ReadInt16(address, length));
                if (result.IsSuccess)
                {
                    Console.WriteLine($"批量读取成功：{string.Join(", ", result.Content)}");
                    return result.Content;
                }
                else
                {
                    Console.WriteLine($"批量读取失败：{result.Message}");
                    return null;
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine($"批量读取异常：{ex.Message}");
                return null;
            }
        }

        public async Task<bool> WriteSingle(string address, short value)
        {
            if (!IsConnected) throw new InvalidOperationException("请先连接到PLC！");
            try
            {
                var result = await Task.Run(() => _melsecMcNet.Write(address, value));
                Console.WriteLine(result.IsSuccess
                    ? $"写入地址 {address} 成功：{value}"
                    : $"写入失败：{result.Message}");
                return result.IsSuccess;
            }
            catch (Exception ex)
            {
                Console.WriteLine($"写入异常：{ex.Message}");
                return false;
            }
        }

        public async Task<bool> WriteBatch(string address, short[] values)
        {
            if (!IsConnected) throw new InvalidOperationException("请先连接到PLC！");
            try
            {
                var result = await Task.Run(() => _melsecMcNet.Write(address, values));
                Console.WriteLine(result.IsSuccess
                    ? $"批量写入成功：{string.Join(", ", values)}"
                    : $"批量写入失败：{result.Message}");
                return result.IsSuccess;
            }
            catch (Exception ex)
            {
                Console.WriteLine($"批量写入异常：{ex.Message}");
                return false;
            }
        }

        public void Disconnect()
        {
            lock (_lock)
            {
                if (IsConnected)
                {
                    _melsecMcNet.ConnectClose();
                    IsConnected = false;
                    Console.WriteLine("已断开与PLC的连接。");
                }
                else
                {
                    Console.WriteLine("PLC未连接，无需断开！");
                }
            }
        }
    }
}
